<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <link rel="stylesheet" href="./style.css" />
  </head>
  <body>
    <div class="container"></div>

    <script>
      const imgList = [
        "1.jpg",
        "2.jpg",
        "3.webp",
        "4.webp",
        "5.jpg",
        "6.jpg",
        "7.jpg",
        "8.webp",
        "9.webp",
        "10.jpg",
      ];

      const containerEl = document.querySelector(".container");

      let timer = null;

      const imgW = 180;

      let isReachBottom = false;

      let pageInfo = {};
      let heightArr = []; //每一列的高度

      // 随机数
      function getRadomInt(min, max) {
        min = Math.ceil(min);
        max = Math.floor(max);
        return Math.floor(Math.random() * (max - min)) + min;
      }

      // 模拟请求图片
      function requestImg() {
        return new Promise(resolve => {
          setTimeout(() => {
            const result = [];
            for (let i = 0; i < pageInfo.col * 2; i++) {
              const index = getRadomInt(0, imgList.length);
              result.push(imgList[index]);
            }
            console.log(result);
            resolve(result);
          }, 300);
        });
      }

      // 触底
      function scrollBottom(speed = 200) {
        if (isReachBottom) {
          return;
        }

        const scrollTop = document.body.scrollTop;
        const currentHeight = scrollTop + window.innerHeight + speed;

        if (currentHeight < document.body.scrollHeight && isReachBottom) {
          isReachBottom = false;
        }
        console.log(currentHeight, document.body.scrollHeight);
        if (currentHeight >= document.body.scrollHeight) {
          isReachBottom = true;
          requestImg().then(res => {
            isReachBottom = false;
            createImg(res);
            const num = Math.max.apply(null, heightArr);
            if (num < window.innerHeight) {
              scrollBottom(speed);
            }
          });
        }
      }

      //创建图片节点
      function createImg(urls = []) {
        urls.forEach(url => {
          const img = document.createElement("img");
          img.style.width = imgW + "px";
          img.src = url;
          containerEl.appendChild(img);
          addAnimation(img);
          img.onload = function () {
            setPos(this);
          };
        });
      }

      // 设置元素位置
      function setPos(dom) {
        const minY = Math.min.apply(null, heightArr);

        const index = heightArr.indexOf(minY);

        const x = index * imgW + (index + 1) * pageInfo.space;

        dom.style.left = x + "px";
        dom.style.top = minY + "px";

        heightArr[index] = heightArr[index] + pageInfo.space + dom.offsetHeight;
        containerEl.style.height = Math.max.apply(null, heightArr) + "px";
      }

      // 计算列数以及间距
      function scalc() {
        const containerW = containerEl.clientWidth - 7;
        const col = Math.floor(containerW / imgW);

        const elseSpace = containerW - col * imgW;

        const space = elseSpace / (col + 1);
        return {
          col,
          space,
        };
      }

      // 添加动画
      const anMap = new WeakMap();
      const ob = new IntersectionObserver(data => {
        for (const item of data) {
          const animation = anMap.get(item.target);
          animation.play();
          ob.unobserve(item.target);
        }
      });
      function addAnimation(el) {
        const animation = el.animate(
          [
            { transform: "translateY(100px)", opacity: 0 },
            { transform: "translateY(0)", opacity: 1 },
          ],
          {
            duration: 500,
            easing: "ease",
          }
        );
        animation.pause();
        anMap.set(el, animation);
        ob.observe(el);
      }

      // 初始化
      function init() {
        pageInfo = scalc();
        heightArr = new Array(pageInfo.col);
        heightArr.fill(pageInfo.space);
      }
      init();

      // 滚动
      document.body.addEventListener("scroll", function () {
        scrollBottom();
      });
      scrollBottom();

      //resize 宽度
      window.onresize = function () {
        if (timer) {
          clearTimeout(timer);
        }
        timer = setTimeout(() => {
          init();
          const imgs = containerEl.querySelectorAll("img");
          for (let i = 0; i < imgs.length; i++) {
            const element = imgs[i];
            setPos(element);
          }
        });
      };
    </script>
  </body>
</html>
